using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;

namespace Pyramid
{
    public partial class Form1 : Form
    {
        StructureTransfer ST;
        Multiresolution MR;
        Blend Bl;
        int Ready2Transfer;
        ImageWithDetail image1;
        ImageWithDetail image2;
        ImageWithDetail image3;
        int detail_counter1, detail_counter2, detail_counter3;
        int level_counter;
        int res_counter;
        Boolean res_done;
        Bitmap Bresult;
        Bitmap Bresult2;
        public Form1()
        {
            InitializeComponent();
            ST = new StructureTransfer();
            image1 = new ImageWithDetail();
            image2 = new ImageWithDetail();
            image3 = new ImageWithDetail();
            Ready2Transfer = 0;
        }
     
        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            OpenFileDialog fdlg = new OpenFileDialog();
            fdlg.Title = "Select the model to open";
           
            fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
            fdlg.RestoreDirectory = true;
            if (fdlg.ShowDialog() == DialogResult.OK)
            {
                Bitmap bmp = (Bitmap)new Bitmap(fdlg.FileName);
                image1.TheImage = new GImage(bmp);
                image1.TheDetails = new List<GImage>();
                pictureBox1.Image = bmp;
                ST.FineImage = new GImage(bmp);
                detail_counter1 = 0;
                Ready2Transfer++;
            }
            pictureBox2.Left = pictureBox1.Left + pictureBox1.Width + 50;
            pictureBox3.Left = pictureBox2.Left + pictureBox2.Width + 50;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            CmbMR.SelectedIndex = 0;
            CmbBlend.SelectedIndex = 0;
            CmbExtension.SelectedIndex = 0;
            image1 = new ImageWithDetail();
            image2 = new ImageWithDetail();
            image3 = new ImageWithDetail();
            toolStripStatusLabel1.Text = "Load the images to start...";
        }

        private void loadCoarseImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog fdlg = new OpenFileDialog();
            fdlg.Title = "Select the image to open";

            fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
            fdlg.RestoreDirectory = true;
            if (fdlg.ShowDialog() == DialogResult.OK)
            {
                Bitmap bmp = (Bitmap)new Bitmap(fdlg.FileName);
                image2.TheImage = new GImage(bmp);
                image2.TheDetails = new List<GImage>();
                pictureBox2.Image = bmp;
                ST.CoarseImage = new GImage(bmp);
                Ready2Transfer++;
            }
           
            pictureBox3.Left = pictureBox2.Left + pictureBox2.Width + 50;
        }

        private void BtnST_Click(object sender, EventArgs e)
        {
           
        }

    
        private void structureTransferToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (ST.CoarseImage!=null && ST.FineImage!=null)
            {
                ST.NeighborhoodSize = 11;
                switch (CmbMR.SelectedIndex)
                {
                    case 0:
                        ST.MR = new CatmullRom();
                        break;
                    case 1:
                        ST.MR = new Chaikin();
                        break;
                    case 2:
                        ST.MR = new ChaikinWithDetail();
                        break;
                    case 3:
                        ST.MR = new Haar();
                        break;
                    case 4:
                        ST.MR = new Faber();
                        break;

                }

                ST.MR.ExtensionMethod = CmbExtension.SelectedIndex;
                ST.MR.Amp_Factor = Convert.ToDouble(TxtAmpfactor.Text);
                ST.MR.AmplifyDetails = chkAmplify.Checked;
                if (ST.Transfer())
                {
                    if (ChkNormalize.Checked)
                        pictureBox3.Image = ST.NewImage.Normalize().ToBitmap();
                    else
                        pictureBox3.Image = ST.NewImage.ToBitmap();
                    image3.TheImage = ST.NewImage;
                    image3.TheDetails = new List<GImage>();
                    image3.TheDetails = new List<GImage>();
                }
            }
            else
                MessageBox.Show ("Load the coarse and fine images");
        }

      
        private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
        {
            initMR();
            switch (e.Button)
            {
                case MouseButtons.Right:
                    if (!ChkDetailView.Checked)
                    {
                        //increase the resolution
                        image1 = MR.UpSample(image1);
                        
                    }
                    else//show the next detail if any
                    {
                        if (image1.TheDetails.Count > 0)
                        {
                        
                           detail_counter1=(detail_counter1+1) % (image1.TheDetails.Count) ;
                        }
                    }
                    break;
                case MouseButtons.Left://decrease the resolution
                    if (!ChkDetailView.Checked)
                    {
                        //increase the resolution
                        image1 = MR.DownSample(image1);
                        
                    }
                    else//show the next detail if any
                    {
                        if (image1.TheDetails.Count > 0)
                        {

                            detail_counter1 = (detail_counter1 + image1.TheDetails.Count - 1) % (image1.TheDetails.Count);
                        }
                    }
                    break;
                case MouseButtons.Middle://save

                    SaveFileDialog sfdg = new SaveFileDialog();

                    sfdg.AddExtension = true;
                    sfdg.RestoreDirectory = true;

                    if (sfdg.ShowDialog() == DialogResult.OK)
                    {
                        pictureBox1.Image.Save(sfdg.FileName);
                    }
                    break;
            }
            if (!ChkDetailView.Checked)
                if (ChkNormalize.Checked)
                    pictureBox1.Image = image1.TheImage.Normalize().ToBitmap();
                else
                pictureBox1.Image = image1.TheImage.ToBitmap();          
            else
                if (image1.TheDetails.Count > 0)
                
                    pictureBox1.Image = image1.TheDetails[(image1.TheDetails.Count - 1 - detail_counter1)].Normalize().ToBitmap();
                
                          
            pictureBox2.Left = pictureBox1.Left + pictureBox1.Width + 50;
            pictureBox3.Left = pictureBox2.Left + pictureBox2.Width + 50;
        }
        private void initMR()
        {
            switch (CmbMR.SelectedIndex)
            {
                case 0:
                    MR = new CatmullRom();
                    break;
                case 1:
                    MR = new Chaikin();
                    break;
                case 2:
                    MR = new ChaikinWithDetail();
                    break;
                case 3:
                    MR = new Haar();
                    break;
                case 4:
                    MR = new Faber();
                    break;

            }
            MR.ExtensionMethod = CmbExtension.SelectedIndex;
            MR.Amp_Factor = Convert.ToDouble(TxtAmpfactor.Text);
            MR.AmplifyDetails = chkAmplify.Checked;
        }

        private void pictureBox2_MouseClick(object sender, MouseEventArgs e)
        {
            initMR();
            switch (e.Button)
            {
                case MouseButtons.Right://increase the resolution

                    image2 = MR.UpSample(image2);
                    
                    break;
                case MouseButtons.Left://decrease the resolution
                    image2 = MR.DownSample(image2);
                    break;
                case MouseButtons.Middle://save

                    SaveFileDialog sfdg = new SaveFileDialog();

                    sfdg.AddExtension = true;
                    sfdg.RestoreDirectory = true;

                    if (sfdg.ShowDialog() == DialogResult.OK)
                    {
                        pictureBox2.Image.Save(sfdg.FileName);
                    }
                    break;
            }
            if (ChkNormalize.Checked)
                pictureBox2.Image = image2.TheImage.Normalize().ToBitmap();
            else
                pictureBox2.Image = image2.TheImage.ToBitmap();
            pictureBox3.Left = pictureBox2.Left + pictureBox2.Width + 50;
        }

        private void pictureBox3_MouseClick(object sender, MouseEventArgs e)
        {
            initMR();
            switch (e.Button)
            {
                case MouseButtons.Right://increase the resolution
                    image3 = MR.UpSample(image3);
                    
                    break;
                case MouseButtons.Left://decrease the resolution
                    image3 = MR.DownSample(image3);
                    break;
                case MouseButtons.Middle://save

                    SaveFileDialog sfdg = new SaveFileDialog();

                    sfdg.AddExtension = true;
                    sfdg.RestoreDirectory = true;

                    if (sfdg.ShowDialog() == DialogResult.OK)
                    {
                        pictureBox3.Image.Save(sfdg.FileName);
                    }
                    break;
            }
            if(ChkNormalize.Checked)
                pictureBox3.Image = image3.TheImage.Normalize().ToBitmap();
            else
                pictureBox3.Image = image3.TheImage.ToBitmap();
        }

        private void blendToolStripMenuItem_Click(object sender, EventArgs e)
        {
            switch (CmbBlend.SelectedIndex)
            {
                case 0:
                    Bl = new ClippedLaplacianBlending();
                    break;
                case 1:
                    Bl = new DetailBlend();
                    
                    break;
                case 2:
                    Bl = new DetailandColorBlend();
                    break;
                case 3:
                    Bl = new LinearInterpolation();
                    break;
                case 4:
                    Bl = new CLBandDetail();
                    break;
            }
            Bl.FineImage = image1.TheImage;
            Bl.CoarseImage = image2.TheImage;
            Bl.AmplifyDetails = chkAmplify.Checked;
            Bl.TransferDetails = ChkAddDetail.Checked;
            Bl.Amp_Factor = Convert.ToDouble(TxtAmpfactor.Text);
            if (Bl.CoarseImage!=null && Bl.FineImage!=null)
            {

                toolStripStatusLabel1.Text = "Blending started...";
                Bl.Init(CmbMR.SelectedIndex,CmbExtension.SelectedIndex);
                Point r;
                if (ChkRegister.Checked)
                    r = Bl.Register_Fine_and_Coarse();

                if (ChkAnalyze.Checked) LblAnalysis.Text = Convert.ToString(Bl.Analyze());
                if (ChkAnimation.Checked)
                {
                    level_counter = 1;
                    res_counter = 1;
                    res_done = true;
                    Bresult = new Bitmap(1, 1);
                    timer1.Enabled = true;
                }
                else
                {
                    image3.TheImage = Bl.IntermediateImage(Convert.ToInt16(TxtLevel.Text));
                    image3.TheDetails = new List<GImage>();
                    if(ChkNormalize.Checked)
                        pictureBox3.Image = image3.TheImage.Normalize().ToBitmap();
                    else
                        pictureBox3.Image = image3.TheImage.ToBitmap();
                    toolStripStatusLabel1.Text = "Blending done...";
                }
            }
            else
                MessageBox.Show("Load the coarse and fine images");

        }

        private void pictureBox2_BackgroundImageChanged(object sender, EventArgs e)
        {
          
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
          
        }

        private void CmbMR_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void BtnPlus_Click(object sender, EventArgs e)
        {
            
            
        }

        private void CmbBlend_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            Point r=image1.TheImage.Register(image1.TheImage,4);

        }

        private void ChkDetailView_CheckedChanged(object sender, EventArgs e)
        {
            if (!ChkDetailView.Checked)
            {
                if(image1.TheImage!=null) 
                    if(ChkNormalize.Checked)
                        pictureBox1.Image = image1.TheImage.Normalize().ToBitmap();
                    else
                        pictureBox1.Image = image1.TheImage.ToBitmap();
            }
            else
                if (image1.TheDetails!=null)
                    if (image1.TheDetails.Count > 0)
                        pictureBox1.Image = image1.TheDetails[(image1.TheDetails.Count - 1 - detail_counter1)].Normalize().ToBitmap();


            pictureBox2.Left = pictureBox1.Left + pictureBox1.Width + 50;
            pictureBox3.Left = pictureBox2.Left + pictureBox2.Width + 50;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            if (res_done)
            {
                
                image3.TheImage = Bl.IntermediateImage(level_counter);
                Bresult = new Bitmap(image3.TheImage.Width, image3.TheImage.Height);
                Bresult = image3.TheImage.ToBitmap();
                res_done = false;
                level_counter++;
                image3.TheImage = Bl.IntermediateImage(level_counter);
                Bresult2 = new Bitmap(image3.TheImage.Width, image3.TheImage.Height);
                Bresult2 = image3.TheImage.ToBitmap();
            }

            if (Bresult != null)
            {
                
                image3.TheDetails = new List<GImage>();
                
                //Bitmap displayimage = new Bitmap();

                Bitmap tempimage = new Bitmap(Bresult.Width + res_counter, Bresult.Height + res_counter);
                Bitmap tempimage2 = new Bitmap(Bresult.Width + res_counter, Bresult.Height + res_counter);
                Graphics g = Graphics.FromImage(tempimage);
                Graphics g2 = Graphics.FromImage(tempimage2);
                g2.DrawImage(Bresult2, 0, 0, tempimage.Width, tempimage.Height);
                double alpha = (1.0) * res_counter / Bresult.Width;
                TextureBrush texture = new TextureBrush(tempimage2);
                g.FillRectangle(texture, new Rectangle(0,0,tempimage.Width, tempimage.Height));
                g.DrawImage(Bresult, 0, 0, tempimage.Width, tempimage.Height);

                 res_counter++;
                if (res_counter == Bresult.Width)
                {
                    res_counter = 1;
                    res_done = true;
                }

                pictureBox3.Image = tempimage;
            }
            timer1.Enabled = true;
        }


    }
}